package com.hsu.apibackend.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradeCloseModel;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryV3Result;
import com.hsu.apibackend.common.ErrorCode;
import com.hsu.apibackend.config.AliPayAccountConfig;
import com.hsu.apibackend.config.EmailConfig;
import com.hsu.apibackend.exception.BusinessException;
import com.hsu.apibackend.mapper.ProductOrderMapper;
import com.hsu.apibackend.model.alipay.AliPayAsyncResponse;
import com.hsu.apibackend.model.entity.ProductInfo;
import com.hsu.apibackend.model.entity.ProductOrder;
import com.hsu.apibackend.model.entity.RechargeActivity;
import com.hsu.apibackend.model.entity.User;
import com.hsu.apibackend.model.enums.AlipayTradeStatusEnum;
import com.hsu.apibackend.model.enums.PaymentStatusEnum;
import com.hsu.apibackend.model.vo.PaymentInfoVO;
import com.hsu.apibackend.model.vo.ProductOrderVO;
import com.hsu.apibackend.model.vo.UserVO;
import com.hsu.apibackend.service.PaymentInfoService;
import com.hsu.apibackend.service.ProductOrderService;
import com.hsu.apibackend.service.RechargeActivityService;
import com.hsu.apibackend.service.UserService;
import com.hsu.apibackend.utils.EmailUtil;
import com.hsu.apibackend.utils.RedissonLockUtil;
import com.ijpay.alipay.AliPayApi;
import com.ijpay.alipay.AliPayApiConfigKit;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Map;

import static com.hsu.apibackend.constant.PayConstant.*;
import static com.hsu.apibackend.model.enums.PayTypeStatusEnum.ALIPAY;
import static com.hsu.apibackend.model.enums.PaymentStatusEnum.*;

/**
 * @Author Hsu琛君珩
 * @Date 2024/09/09
 * @Version 1.0
 * @Description: 实现与支付宝支付相关的订单处理逻辑
 */
@Service
@Slf4j
@Qualifier("ALIPAY")
public class AlipayOrderServiceImpl extends ServiceImpl<ProductOrderMapper, ProductOrder> implements ProductOrderService {

    @Resource
    private EmailConfig emailConfig;
    @Resource
    private JavaMailSender mailSender;
    @Resource
    private AliPayAccountConfig aliPayAccountConfig;
    @Resource
    private UserService userService;
    @Resource
    private ProductInfoServiceImpl productInfoService;

    @Resource
    private PaymentInfoService paymentInfoService;
    @Resource
    private RedissonLockUtil redissonLockUtil;
    @Resource
    private RechargeActivityService rechargeActivityService;

    /**
     * 获取用户的产品订单信息
     *
     * @param productId 产品ID
     * @param loginUser 当前登录用户信息
     * @param payType   支付类型（如微信支付、支付宝等）
     * @return {@link ProductOrderVO} 包含订单信息的对象，如果没有找到订单则返回 null
     */
    @Override
    public ProductOrderVO getProductOrder(Long productId, UserVO loginUser, String payType) {
        // 构建查询条件
        LambdaQueryWrapper<ProductOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 根据产品ID查询
        lambdaQueryWrapper.eq(ProductOrder::getProductId, productId);
        // 状态为未支付
        lambdaQueryWrapper.eq(ProductOrder::getStatus, PaymentStatusEnum.NOTPAY.getValue());
        // 支付类型匹配
        lambdaQueryWrapper.eq(ProductOrder::getPayType, payType);
        // 订单属于当前用户
        lambdaQueryWrapper.eq(ProductOrder::getUserId, loginUser.getId());

        // 查询是否有未支付的订单
        ProductOrder oldOrder = this.getOne(lambdaQueryWrapper);
        if (oldOrder == null) {
            return null;
        }

        // 创建并填充返回对象
        ProductOrderVO productOrderVO = new ProductOrderVO();
        BeanUtils.copyProperties(oldOrder, productOrderVO);

        // 解析产品信息并设置
        productOrderVO.setProductInfo(JSONUtil.toBean(oldOrder.getProductInfo(), ProductInfo.class));
        // 设置订单总金额
        productOrderVO.setTotal(oldOrder.getTotal().toString());

        // 返回订单信息
        return productOrderVO;
    }

    /**
     * 保存产品订单
     *
     * @param productId 产品ID
     * @param loginUser 当前登录的用户信息
     * @return {@link ProductOrderVO} 包含订单信息的对象
     */
    @Override
    public ProductOrderVO saveProductOrder(Long productId, UserVO loginUser) {
        // 根据产品ID获取商品信息
        ProductInfo productInfo = productInfoService.getById(productId);
        if (productInfo == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "商品不存在");
        }

        // 设置订单的有效期为5分钟
        Date date = DateUtil.date(System.currentTimeMillis());
        Date expirationTime = DateUtil.offset(date, DateField.MINUTE, 5);

        // 生成订单号
        String orderNo = ORDER_PREFIX + RandomUtil.randomNumbers(20);

        // 构建产品订单对象
        ProductOrder productOrder = new ProductOrder();
        productOrder.setUserId(loginUser.getId());
        productOrder.setOrderNo(orderNo);
        productOrder.setProductId(productInfo.getId());
        productOrder.setOrderName(productInfo.getName());
        productOrder.setTotal(productInfo.getTotal());
        productOrder.setStatus(PaymentStatusEnum.NOTPAY.getValue());  // 设置订单状态为未支付
        productOrder.setPayType(ALIPAY.getValue());  // 默认支付类型为支付宝
        productOrder.setExpirationTime(expirationTime);  // 设置订单过期时间
        productOrder.setProductInfo(JSONUtil.toJsonPrettyStr(productInfo));  // 保存商品信息为JSON格式
        productOrder.setAddPoints(productInfo.getAddPoints());  // 设置积分

        // 保存订单
        boolean saveResult = this.save(productOrder);

        // 构建支付宝支付请求参数
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setOutTradeNo(orderNo);
        model.setSubject(productInfo.getName());
        model.setProductCode("FAST_INSTANT_TRADE_PAY");

        // 将金额转换为元，四舍五入保留两位小数
        BigDecimal scaledAmount = new BigDecimal(productInfo.getTotal())
                .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
        model.setTotalAmount(String.valueOf(scaledAmount));
        model.setBody(productInfo.getDescription());

        // 设置支付请求和回调地址
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setBizModel(model);
        request.setNotifyUrl(aliPayAccountConfig.getNotifyUrl());
        request.setReturnUrl(aliPayAccountConfig.getReturnUrl());

        try {
            // 发送支付宝支付请求，获取支付页面URL
            AlipayTradePagePayResponse alipayTradePagePayResponse = AliPayApi.pageExecute(request);
            String payUrl = alipayTradePagePayResponse.getBody();
            productOrder.setFormData(payUrl);  // 保存支付页面URL到订单
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }

        // 更新订单信息
        boolean updateResult = this.updateProductOrder(productOrder);
        if (!updateResult && !saveResult) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }

        // 构建返回对象VO
        ProductOrderVO productOrderVO = new ProductOrderVO();
        BeanUtils.copyProperties(productOrder, productOrderVO);
        productOrderVO.setProductInfo(productInfo);  // 设置产品信息
        productOrderVO.setTotal(productInfo.getTotal().toString());  // 设置订单总金额

        // 返回订单信息
        return productOrderVO;
    }

    /**
     * 更新产品订单的支付表单数据
     *
     * @param productOrder 包含需要更新的订单信息
     * @return 更新是否成功
     */
    @Override
    public boolean updateProductOrder(ProductOrder productOrder) {
        // 获取订单中的支付表单数据
        String formData = productOrder.getFormData();

        // 获取订单ID
        Long id = productOrder.getId();

        // 创建新的订单对象用于更新
        ProductOrder updateCodeUrl = new ProductOrder();
        updateCodeUrl.setFormData(formData);  // 设置新的支付表单数据
        updateCodeUrl.setId(id);  // 设置订单ID

        // 根据订单ID更新订单信息
        return this.updateById(updateCodeUrl);
    }

    /**
     * 根据订单编号更新订单状态
     *
     * @param outTradeNo 订单编号
     * @param orderStatus 要更新的订单状态
     * @return 更新是否成功
     */
    @Override
    public boolean updateOrderStatusByOrderNo(String outTradeNo, String orderStatus) {
        // 创建新的订单对象并设置要更新的状态
        ProductOrder productOrder = new ProductOrder();
        productOrder.setStatus(orderStatus);  // 设置新的订单状态

        // 构建查询条件，通过订单编号匹配订单
        LambdaQueryWrapper<ProductOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ProductOrder::getOrderNo, outTradeNo);  // 使用订单编号作为查询条件

        // 更新订单状态
        return this.update(productOrder, lambdaQueryWrapper);
    }

    /**
     * 根据订单编号关闭订单
     *
     * @param outTradeNo 订单编号
     * @throws AlipayApiException 支付宝接口调用异常
     */
    @Override
    public void closedOrderByOrderNo(String outTradeNo) throws AlipayApiException {
        // 创建支付宝关闭订单的请求模型
        AlipayTradeCloseModel alipayTradeCloseModel = new AlipayTradeCloseModel();
        alipayTradeCloseModel.setOutTradeNo(outTradeNo);  // 设置订单编号

        // 创建关闭订单请求对象
        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
        request.setBizModel(alipayTradeCloseModel);  // 将请求模型设置到请求对象中

        // 执行关闭订单请求
        AliPayApi.doExecute(request);
    }

    /**
     * 根据外部交易号获取产品订单
     *
     * @param outTradeNo 外部交易号
     * @return {@link ProductOrder} 对应的产品订单信息
     */
    @Override
    public ProductOrder getProductOrderByOutTradeNo(String outTradeNo) {
        // 创建查询条件，按照订单号查询
        LambdaQueryWrapper<ProductOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ProductOrder::getOrderNo, outTradeNo);  // 设置订单号条件

        // 执行查询并返回订单信息
        return this.getOne(lambdaQueryWrapper);
    }

    /**
     * 处理超时订单
     *
     * 该方法会查询超时的订单状态，如果支付宝没有记录该订单，或者订单未支付，
     * 则关闭该订单并更新本地状态。如果订单已支付，更新订单状态并给用户增加积分，同时保存支付记录。
     *
     * @param productOrder 超时的产品订单信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void processingTimedOutOrders(ProductOrder productOrder) {
        String orderNo = productOrder.getOrderNo();
        try {
            // 查询订单状态
            AlipayTradeQueryModel alipayTradeQueryModel = new AlipayTradeQueryModel();
            alipayTradeQueryModel.setOutTradeNo(orderNo);
            AlipayTradeQueryResponse alipayTradeQueryResponse = AliPayApi.tradeQueryToResponse(alipayTradeQueryModel);

            // 本地创建了订单，但支付宝没有记录（用户未扫码）
            if (!alipayTradeQueryResponse.getCode().equals(RESPONSE_CODE_SUCCESS)) {
                // 更新本地订单状态为已关闭
                this.updateOrderStatusByOrderNo(orderNo, PaymentStatusEnum.CLOSED.getValue());
                log.info("超时订单{},更新成功", orderNo);
                return;
            }

            String tradeStatus = AlipayTradeStatusEnum.findByName(alipayTradeQueryResponse.getTradeStatus())
                    .getPaymentStatusEnum().getValue();

            // 如果订单未支付或已关闭，关闭订单并更新本地状态
            if (tradeStatus.equals(NOTPAY.getValue()) || tradeStatus.equals(CLOSED.getValue())) {
                closedOrderByOrderNo(orderNo);  // 关闭支付宝端订单
                this.updateOrderStatusByOrderNo(orderNo, PaymentStatusEnum.CLOSED.getValue());  // 更新本地状态
                log.info("超时订单{},关闭成功", orderNo);
                return;
            }

            // 如果订单已支付，更新本地状态为成功
            if (tradeStatus.equals(SUCCESS.getValue())) {
                boolean updateOrderStatus = this.updateOrderStatusByOrderNo(orderNo, SUCCESS.getValue());
                // 为用户增加积分
                boolean addWalletBalance = userService.addWalletBalance(productOrder.getUserId(), productOrder.getAddPoints());

                // 创建并保存支付记录
                PaymentInfoVO paymentInfoVO = new PaymentInfoVO();
                paymentInfoVO.setAppid(aliPayAccountConfig.getAppId());
                paymentInfoVO.setOutTradeNo(alipayTradeQueryResponse.getOutTradeNo());
                paymentInfoVO.setTransactionId(alipayTradeQueryResponse.getTradeNo());
                paymentInfoVO.setTradeType("电脑网站支付");
                paymentInfoVO.setTradeState(alipayTradeQueryResponse.getTradeStatus());
                paymentInfoVO.setTradeStateDesc("支付成功");
                paymentInfoVO.setSuccessTime(String.valueOf(alipayTradeQueryResponse.getSendPayDate()));

                WxPayOrderQueryV3Result.Payer payer = new WxPayOrderQueryV3Result.Payer();
                payer.setOpenid(alipayTradeQueryResponse.getBuyerOpenId());
                paymentInfoVO.setPayer(payer);

                WxPayOrderQueryV3Result.Amount amount = new WxPayOrderQueryV3Result.Amount();
                amount.setTotal(new BigDecimal(alipayTradeQueryResponse.getTotalAmount()).multiply(new BigDecimal("100")).intValue());
                amount.setPayerTotal(new BigDecimal(alipayTradeQueryResponse.getReceiptAmount()).multiply(new BigDecimal("100")).intValue());
                amount.setCurrency(alipayTradeQueryResponse.getPayCurrency());
                amount.setPayerCurrency(alipayTradeQueryResponse.getPayCurrency());
                paymentInfoVO.setAmount(amount);

                boolean paymentResult = paymentInfoService.createPaymentInfo(paymentInfoVO);

                // 检查更新订单状态、增加积分和保存支付记录是否成功
                if (!updateOrderStatus & !addWalletBalance & !paymentResult) {
                    throw new BusinessException(ErrorCode.OPERATION_ERROR);
                }

                // 更新活动表
                saveRechargeActivity(productOrder);

                // 发送支付成功邮件
                sendSuccessEmail(productOrder, alipayTradeQueryResponse.getTotalAmount());

                log.info("超时订单{},更新成功", orderNo);
            }
        } catch (AlipayApiException e) {
            // 处理过程中出错，记录日志并抛出异常
            log.error("订单{} 处理失败", orderNo);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, e.getMessage());
        }
    }

    /**
     * 发送支付成功邮件
     *
     * 该方法用于在订单支付成功后，向用户发送支付成功的通知邮件。
     * 如果用户的邮箱不为空，则会尝试发送邮件。
     *
     * @param productOrder 产品订单信息
     * @param orderTotal   订单总金额
     */
    private void sendSuccessEmail(ProductOrder productOrder, String orderTotal) {
        // 获取用户信息
        User user = userService.getById(productOrder.getUserId());

        // 检查用户是否有邮箱
        if (StringUtils.isNotBlank(user.getEmail())) {
            try {
                // 根据交易号获取订单信息
                ProductOrder productOrderByOutTradeNo = this.getProductOrderByOutTradeNo(productOrder.getOrderNo());

                // 发送支付成功邮件
                new EmailUtil().sendPaySuccessEmail(
                        user.getEmail(),
                        mailSender,
                        emailConfig,
                        productOrderByOutTradeNo.getOrderName(),
                        String.valueOf(orderTotal)
                );
                log.info("发送邮件：{}，成功", user.getEmail());
            } catch (Exception e) {
                // 记录发送失败的日志
                log.error("发送邮件：{}，失败：{}", user.getEmail(), e.getMessage());
            }
        }
    }

    /**
     * 处理支付宝支付异步通知
     *
     * 该方法用于处理支付宝的异步通知，验证并更新订单状态。方法内部使用分布式锁，确保订单处理的幂等性。
     *
     * @param notifyData 支付宝回调的通知数据
     * @param request    Http请求对象，用于获取请求参数
     * @return 处理结果字符串，返回给支付宝的响应
     * @throws BusinessException 如果处理过程中发生错误，则抛出业务异常
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String doPaymentNotify(String notifyData, HttpServletRequest request) {
        // 将支付宝回调请求的参数转换为Map
        Map<String, String> params = AliPayApi.toMap(request);

        // 将参数转换为支付宝异步回调响应对象
        AliPayAsyncResponse aliPayAsyncResponse = JSONUtil.toBean(JSONUtil.toJsonStr(params), AliPayAsyncResponse.class);

        // 分布式锁的名称，基于订单号生成，确保幂等性
        String lockName = "notify:AlipayOrder:lock:" + aliPayAsyncResponse.getOutTradeNo();

        // 使用Redisson分布式锁，确保同一订单不会被多次处理
        return redissonLockUtil.redissonDistributedLocks(lockName, "【支付宝异步回调异常】:", () -> {
            String result;
            try {
                // 校验支付宝订单
                result = checkAlipayOrder(aliPayAsyncResponse, params);
            } catch (AlipayApiException e) {
                // 捕获异常并抛出业务异常
                throw new BusinessException(ErrorCode.OPERATION_ERROR, e.getMessage());
            }

            // 校验失败则返回错误信息
            if (!"success".equals(result)) {
                return result;
            }

            // 执行支付宝订单的业务处理逻辑
            String doAliPayOrderBusinessResult = this.doAliPayOrderBusiness(aliPayAsyncResponse);

            // 如果处理结果为空，抛出业务异常
            if (StringUtils.isBlank(doAliPayOrderBusinessResult)) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR);
            }

            // 返回业务处理结果
            return doAliPayOrderBusinessResult;
        });
    }

    /**
     * 校验支付宝订单信息
     *
     * 该方法用于校验支付宝异步通知中的订单信息是否与商户系统中保存的订单信息一致。
     *
     * @param response 支付宝异步回调响应数据对象
     * @param params   回调请求中的参数Map
     * @return 返回 "success" 表示校验通过，返回 "failure" 表示校验失败
     * @throws AlipayApiException 如果签名校验失败，则抛出支付宝API异常
     */
    private String checkAlipayOrder(AliPayAsyncResponse response, Map<String, String> params) throws AlipayApiException {
        String result = "failure";

        // 校验支付宝回调的签名，确保数据的完整性与合法性
        boolean verifyResult = AlipaySignature.rsaCheckV1(params,
                AliPayApiConfigKit.getAliPayApiConfig().getAliPayPublicKey(),
                AliPayApiConfigKit.getAliPayApiConfig().getCharset(),
                AliPayApiConfigKit.getAliPayApiConfig().getSignType());

        // 如果签名校验失败，直接返回失败结果
        if (!verifyResult) {
            return result;
        }
        // 1. 验证 out_trade_no 是否为商家系统中创建的订单号
        ProductOrder productOrder = this.getProductOrderByOutTradeNo(response.getOutTradeNo());
        if (productOrder == null) {
            log.error("订单不存在");
            return result;
        }
        // 2. 验证 total_amount 是否为该订单的实际金额
        int totalAmount = new BigDecimal(response.getTotalAmount()).multiply(new BigDecimal("100")).intValue();
        if (totalAmount != productOrder.getTotal()) {
            log.error("订单金额不一致");
            return result;
        }
        // 3. 校验通知中的 seller_id 是否与商户的 seller_id 一致
        String sellerId = aliPayAccountConfig.getSellerId();
        if (!response.getSellerId().equals(sellerId)) {
            log.error("卖家账号校验失败");
            return result;
        }
        // 4. 验证 app_id 是否为商户的 app_id
        String appId = aliPayAccountConfig.getAppId();
        if (!response.getAppId().equals(appId)) {
            log.error("校验失败");
            return result;
        }

        // 校验交易状态是否为 "TRADE_SUCCESS"
        String tradeStatus = response.getTradeStatus();
        if (!tradeStatus.equals(TRADE_SUCCESS)) {
            log.error("交易失败");
            return result;
        }

        // 所有校验通过，返回 "success"
        return "success";
    }

    /**
     * 处理支付宝订单业务逻辑
     *
     * 该方法处理来自支付宝的异步支付通知，更新订单状态、用户积分，并保存支付记录。
     * 如果支付成功，则会执行相关业务操作并返回 "success"。
     * 如果业务处理失败，则抛出业务异常。
     *
     * @param response 支付宝异步通知的响应对象
     * @return 返回支付结果处理的状态
     * @throws BusinessException 如果业务处理出现错误，抛出操作错误异常
     */
    @SneakyThrows
    protected String doAliPayOrderBusiness(AliPayAsyncResponse response) {
        // 获取订单号
        String outTradeNo = response.getOutTradeNo();
        ProductOrder productOrder = this.getProductOrderByOutTradeNo(outTradeNo);

        // 如果订单已经是成功状态，直接返回 "success"
        if (SUCCESS.getValue().equals(productOrder.getStatus())) {
            return "success";
        }

        // 更新订单状态
        boolean updateOrderStatus = this.updateOrderStatusByOrderNo(outTradeNo, SUCCESS.getValue());

        // 更新用户积分余额
        boolean addWalletBalance = userService.addWalletBalance(productOrder.getUserId(), productOrder.getAddPoints());

        // 保存支付记录信息
        PaymentInfoVO paymentInfoVO = new PaymentInfoVO();
        paymentInfoVO.setAppid(response.getAppId());
        paymentInfoVO.setOutTradeNo(response.getOutTradeNo());
        paymentInfoVO.setTransactionId(response.getTradeNo());
        paymentInfoVO.setTradeType("电脑网站支付");
        paymentInfoVO.setTradeState(response.getTradeStatus());
        paymentInfoVO.setTradeStateDesc("支付成功");
        paymentInfoVO.setSuccessTime(response.getNotifyTime());

        // 设置支付人信息
        WxPayOrderQueryV3Result.Payer payer = new WxPayOrderQueryV3Result.Payer();
        payer.setOpenid(response.getBuyerId());
        paymentInfoVO.setPayer(payer);

        // 设置金额信息
        WxPayOrderQueryV3Result.Amount amount = new WxPayOrderQueryV3Result.Amount();
        amount.setTotal(new BigDecimal(response.getTotalAmount()).multiply(new BigDecimal("100")).intValue());
        amount.setPayerTotal(new BigDecimal(response.getReceiptAmount()).multiply(new BigDecimal("100")).intValue());
        amount.setCurrency("CNY");
        amount.setPayerCurrency("CNY");
        paymentInfoVO.setAmount(amount);

        // 创建支付信息记录
        boolean paymentResult = paymentInfoService.createPaymentInfo(paymentInfoVO);

        // 更新活动表
        boolean rechargeActivity = saveRechargeActivity(productOrder);

        // 如果所有操作成功，则发送邮件并返回 "success"
        if (paymentResult && updateOrderStatus && addWalletBalance && rechargeActivity) {
            log.info("【支付回调通知处理成功】");

            // 发送支付成功邮件通知
            sendSuccessEmail(productOrder, response.getTotalAmount());
            return "success";
        }

        // 如果业务处理失败，抛出操作错误异常
        throw new BusinessException(ErrorCode.OPERATION_ERROR);
    }

    /**
     * 保存充值活动
     *
     * 该方法用于在用户充值成功后，将相关充值活动信息保存到活动表中。
     * 如果保存操作失败，会抛出业务异常。
     *
     * @param productOrder 产品订单信息，包含用户ID、产品ID等信息
     * @return 如果保存成功，返回 true；否则抛出异常
     * @throws BusinessException 如果保存操作失败，抛出操作错误异常
     */
    private boolean saveRechargeActivity(ProductOrder productOrder) {
        // 创建充值活动实体
        RechargeActivity rechargeActivity = new RechargeActivity();

        // 设置用户ID、产品ID和订单号
        rechargeActivity.setUserId(productOrder.getUserId());
        rechargeActivity.setProductId(productOrder.getProductId());
        rechargeActivity.setOrderNo(productOrder.getOrderNo());

        // 保存充值活动信息
        boolean save = rechargeActivityService.save(rechargeActivity);

        // 如果保存失败，抛出业务异常
        if (!save) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "保存失败");
        }

        // 保存成功返回 true
        return true;
    }

}
